1/* 2 * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6#include <arch.h> 7#include <asm_macros.S> 8#include <pl011.h> 9 10/* 11 * Pull in generic functions to provide backwards compatibility for 12 * platform makefiles 13 */ 14#include "../../../console/aarch32/console.S" 15 16 .globl console_core_init 17 .globl console_core_putc 18 .globl console_core_getc 19 .globl console_core_flush 20 21 22 /* ----------------------------------------------- 23 * int console_core_init(uintptr_t base_addr, 24 * unsigned int uart_clk, unsigned int baud_rate) 25 * Function to initialize the console without a 26 * C Runtime to print debug information. This 27 * function will be accessed by console_init and 28 * crash reporting. 29 * In: r0 - console base address 30 * r1 - Uart clock in Hz 31 * r2 - Baud rate 32 * Out: return 1 on success else 0 on error 33 * Clobber list : r1, r2, r3 34 * ----------------------------------------------- 35 */ 36func console_core_init 37 /* Check the input base address */ 38 cmp r0, #0 39 beq core_init_fail 40#if !PL011_GENERIC_UART 41 /* Check baud rate and uart clock for sanity */ 42 cmp r1, #0 43 beq core_init_fail 44 cmp r2, #0 45 beq core_init_fail 46 /* Disable the UART before initialization */ 47 ldr r3, [r0, #UARTCR] 48 bic r3, r3, #PL011_UARTCR_UARTEN 49 str r3, [r0, #UARTCR] 50 /* Program the baudrate */ 51 /* Divisor = (Uart clock * 4) / baudrate */ 52 lsl r1, r1, #2 53 udiv r2, r1, r2 54 /* IBRD = Divisor >> 6 */ 55 lsr r1, r2, #6 56 /* Write the IBRD */ 57 str r1, [r0, #UARTIBRD] 58 /* FBRD = Divisor & 0x3F */ 59 and r1, r2, #0x3f 60 /* Write the FBRD */ 61 str r1, [r0, #UARTFBRD] 62 mov r1, #PL011_LINE_CONTROL 63 str r1, [r0, #UARTLCR_H] 64 /* Clear any pending errors */ 65 mov r1, #0 66 str r1, [r0, #UARTECR] 67 /* Enable tx, rx, and uart overall */ 68 ldr r1, =(PL011_UARTCR_RXE | PL011_UARTCR_TXE | PL011_UARTCR_UARTEN) 69 str r1, [r0, #UARTCR] 70#endif 71 mov r0, #1 72 bx lr 73core_init_fail: 74 mov r0, #0 75 bx lr 76endfunc console_core_init 77 78 /* -------------------------------------------------------- 79 * int console_core_putc(int c, uintptr_t base_addr) 80 * Function to output a character over the console. It 81 * returns the character printed on success or -1 on error. 82 * In : r0 - character to be printed 83 * r1 - console base address 84 * Out : return -1 on error else return character. 85 * Clobber list : r2 86 * -------------------------------------------------------- 87 */ 88func console_core_putc 89 /* Check the input parameter */ 90 cmp r1, #0 91 beq putc_error 92 /* Prepend '\r' to '\n' */ 93 cmp r0, #0xA 94 bne 2f 951: 96 /* Check if the transmit FIFO is full */ 97 ldr r2, [r1, #UARTFR] 98 tst r2, #PL011_UARTFR_TXFF 99 bne 1b 100 mov r2, #0xD 101 str r2, [r1, #UARTDR] 1022: 103 /* Check if the transmit FIFO is full */ 104 ldr r2, [r1, #UARTFR] 105 tst r2, #PL011_UARTFR_TXFF 106 bne 2b 107 str r0, [r1, #UARTDR] 108 bx lr 109putc_error: 110 mov r0, #-1 111 bx lr 112endfunc console_core_putc 113 114 /* --------------------------------------------- 115 * int console_core_getc(uintptr_t base_addr) 116 * Function to get a character from the console. 117 * It returns the character grabbed on success 118 * or -1 on error. 119 * In : r0 - console base address 120 * Clobber list : r0, r1 121 * --------------------------------------------- 122 */ 123func console_core_getc 124 cmp r0, #0 125 beq getc_error 1261: 127 /* Check if the receive FIFO is empty */ 128 ldr r1, [r0, #UARTFR] 129 tst r1, #PL011_UARTFR_RXFE 130 bne 1b 131 ldr r1, [r0, #UARTDR] 132 mov r0, r1 133 bx lr 134getc_error: 135 mov r0, #-1 136 bx lr 137endfunc console_core_getc 138 139 /* --------------------------------------------- 140 * int console_core_flush(uintptr_t base_addr) 141 * Function to force a write of all buffered 142 * data that hasn't been output. 143 * In : r0 - console base address 144 * Out : return -1 on error else return 0. 145 * Clobber list : r0, r1 146 * --------------------------------------------- 147 */ 148func console_core_flush 149 cmp r0, #0 150 beq flush_error 151 1521: 153 /* Loop while the transmit FIFO is busy */ 154 ldr r1, [r0, #UARTFR] 155 tst r1, #PL011_UARTFR_BUSY 156 bne 1b 157 158 mov r0, #0 159 bx lr 160flush_error: 161 mov r0, #-1 162 bx lr 163endfunc console_core_flush 164