1/* 2 * Copyright (c) 2013-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/aarch64/console.S" 15 16 17 .globl console_core_init 18 .globl console_core_putc 19 .globl console_core_getc 20 .globl console_core_flush 21 22 23 /* ----------------------------------------------- 24 * int console_core_init(uintptr_t base_addr, 25 * unsigned int uart_clk, unsigned int baud_rate) 26 * Function to initialize the console without a 27 * C Runtime to print debug information. This 28 * function will be accessed by console_init and 29 * crash reporting. 30 * In: x0 - console base address 31 * w1 - Uart clock in Hz 32 * w2 - Baud rate 33 * Out: return 1 on success else 0 on error 34 * Clobber list : x1, x2, x3, x4 35 * ----------------------------------------------- 36 */ 37func console_core_init 38 /* Check the input base address */ 39 cbz x0, core_init_fail 40#if !PL011_GENERIC_UART 41 /* Check baud rate and uart clock for sanity */ 42 cbz w1, core_init_fail 43 cbz w2, core_init_fail 44 /* Disable uart before programming */ 45 ldr w3, [x0, #UARTCR] 46 mov w4, #PL011_UARTCR_UARTEN 47 bic w3, w3, w4 48 str w3, [x0, #UARTCR] 49 /* Program the baudrate */ 50 /* Divisor = (Uart clock * 4) / baudrate */ 51 lsl w1, w1, #2 52 udiv w2, w1, w2 53 /* IBRD = Divisor >> 6 */ 54 lsr w1, w2, #6 55 /* Write the IBRD */ 56 str w1, [x0, #UARTIBRD] 57 /* FBRD = Divisor & 0x3F */ 58 and w1, w2, #0x3f 59 /* Write the FBRD */ 60 str w1, [x0, #UARTFBRD] 61 mov w1, #PL011_LINE_CONTROL 62 str w1, [x0, #UARTLCR_H] 63 /* Clear any pending errors */ 64 str wzr, [x0, #UARTECR] 65 /* Enable tx, rx, and uart overall */ 66 mov w1, #(PL011_UARTCR_RXE | PL011_UARTCR_TXE | PL011_UARTCR_UARTEN) 67 str w1, [x0, #UARTCR] 68#endif 69 mov w0, #1 70 ret 71core_init_fail: 72 mov w0, wzr 73 ret 74endfunc console_core_init 75 76 /* -------------------------------------------------------- 77 * int console_core_putc(int c, uintptr_t base_addr) 78 * Function to output a character over the console. It 79 * returns the character printed on success or -1 on error. 80 * In : w0 - character to be printed 81 * x1 - console base address 82 * Out : return -1 on error else return character. 83 * Clobber list : x2 84 * -------------------------------------------------------- 85 */ 86func console_core_putc 87 /* Check the input parameter */ 88 cbz x1, putc_error 89 /* Prepend '\r' to '\n' */ 90 cmp w0, #0xA 91 b.ne 2f 921: 93 /* Check if the transmit FIFO is full */ 94 ldr w2, [x1, #UARTFR] 95 tbnz w2, #PL011_UARTFR_TXFF_BIT, 1b 96 mov w2, #0xD 97 str w2, [x1, #UARTDR] 982: 99 /* Check if the transmit FIFO is full */ 100 ldr w2, [x1, #UARTFR] 101 tbnz w2, #PL011_UARTFR_TXFF_BIT, 2b 102 str w0, [x1, #UARTDR] 103 ret 104putc_error: 105 mov w0, #-1 106 ret 107endfunc console_core_putc 108 109 /* --------------------------------------------- 110 * int console_core_getc(uintptr_t base_addr) 111 * Function to get a character from the console. 112 * It returns the character grabbed on success 113 * or -1 on error. 114 * In : x0 - console base address 115 * Clobber list : x0, x1 116 * --------------------------------------------- 117 */ 118func console_core_getc 119 cbz x0, getc_error 1201: 121 /* Check if the receive FIFO is empty */ 122 ldr w1, [x0, #UARTFR] 123 tbnz w1, #PL011_UARTFR_RXFE_BIT, 1b 124 ldr w1, [x0, #UARTDR] 125 mov w0, w1 126 ret 127getc_error: 128 mov w0, #-1 129 ret 130endfunc console_core_getc 131 132 /* --------------------------------------------- 133 * int console_core_flush(uintptr_t base_addr) 134 * Function to force a write of all buffered 135 * data that hasn't been output. 136 * In : x0 - console base address 137 * Out : return -1 on error else return 0. 138 * Clobber list : x0, x1 139 * --------------------------------------------- 140 */ 141func console_core_flush 142 cbz x0, flush_error 143 1441: 145 /* Loop until the transmit FIFO is empty */ 146 ldr w1, [x0, #UARTFR] 147 tbnz w1, #PL011_UARTFR_BUSY_BIT, 1b 148 149 mov w0, #0 150 ret 151flush_error: 152 mov w0, #-1 153 ret 154endfunc console_core_flush 155