1/* 2 * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6#include <asm_macros.S> 7#include <uart8250.h> 8 9 .globl console_core_init 10 .globl console_core_putc 11 .globl console_core_getc 12 .globl console_core_flush 13 14 /* ----------------------------------------------- 15 * int console_core_init(unsigned long base_addr, 16 * unsigned int uart_clk, unsigned int baud_rate) 17 * Function to initialize the console without a 18 * C Runtime to print debug information. This 19 * function will be accessed by console_init and 20 * crash reporting. 21 * In: x0 - console base address 22 * w1 - Uart clock in Hz 23 * w2 - Baud rate 24 * Out: return 1 on success else 0 on error 25 * Clobber list : x1, x2, x3 26 * ----------------------------------------------- 27 */ 28func console_core_init 29 /* Check the input base address */ 30 cbz x0, core_init_fail 31 /* Check baud rate and uart clock for sanity */ 32 cbz w1, core_init_fail 33 cbz w2, core_init_fail 34 35 /* Disable interrupt */ 36 str wzr, [x0, #UART_IER] 37 38 /* Force DTR and RTS to high */ 39 mov w3, #(UART_MCR_DTR | UART_MCR_RTS) 40 str w3, [x0, #UART_MCR] 41 42 /* Check high speed */ 43 movz w3, #:abs_g1:115200 44 movk w3, #:abs_g0_nc:115200 45 cmp w2, w3 46 b.hi 1f 47 48 /* Non high speed */ 49 lsl w2, w2, #4 50 mov w3, wzr 51 b 2f 52 53 /* High speed */ 541: lsl w2, w2, #2 55 mov w3, #2 56 57 /* Set high speed UART register */ 582: str w3, [x0, #UART_HIGHSPEED] 59 60 /* Calculate divisor */ 61 udiv w3, w1, w2 /* divisor = uartclk / (quot * baudrate) */ 62 msub w1, w3, w2, w1 /* remainder = uartclk % (quot * baudrate) */ 63 lsr w2, w2, #1 64 cmp w1, w2 65 cinc w3, w3, hs 66 67 /* Set line configuration, access divisor latches */ 68 mov w1, #(UART_LCR_DLAB | UART_LCR_WLS_8) 69 str w1, [x0, #UART_LCR] 70 71 /* Set the divisor */ 72 and w1, w3, #0xff 73 str w1, [x0, #UART_DLL] 74 lsr w1, w3, #8 75 and w1, w1, #0xff 76 str w1, [x0, #UART_DLH] 77 78 /* Hide the divisor latches */ 79 mov w1, #UART_LCR_WLS_8 80 str w1, [x0, #UART_LCR] 81 82 /* Enable FIFOs, and clear receive and transmit */ 83 mov w1, #(UART_FCR_FIFO_EN | UART_FCR_CLEAR_RCVR | \ 84 UART_FCR_CLEAR_XMIT) 85 str w1, [x0, #UART_FCR] 86 87 mov w0, #1 88 ret 89core_init_fail: 90 mov w0, wzr 91 ret 92endfunc console_core_init 93 94 /* -------------------------------------------------------- 95 * int console_core_putc(int c, unsigned long base_addr) 96 * Function to output a character over the console. It 97 * returns the character printed on success or -1 on error. 98 * In : w0 - character to be printed 99 * x1 - console base address 100 * Out : return -1 on error else return character. 101 * Clobber list : x2 102 * -------------------------------------------------------- 103 */ 104func console_core_putc 105 /* Check the input parameter */ 106 cbz x1, putc_error 107 /* Prepend '\r' to '\n' */ 108 cmp w0, #0xA 109 b.ne 2f 110 111 /* Check if the transmit FIFO is full */ 1121: ldr w2, [x1, #UART_LSR] 113 and w2, w2, #UART_LSR_THRE 114 cbz w2, 1b 115 mov w2, #0xD 116 str w2, [x1, #UART_THR] 117 118 /* Check if the transmit FIFO is full */ 1192: ldr w2, [x1, #UART_LSR] 120 and w2, w2, #UART_LSR_THRE 121 cbz w2, 2b 122 str w0, [x1, #UART_THR] 123 ret 124putc_error: 125 mov w0, #-1 126 ret 127endfunc console_core_putc 128 129 /* --------------------------------------------- 130 * int console_core_getc(unsigned long base_addr) 131 * Function to get a character from the console. 132 * It returns the character grabbed on success 133 * or -1 on error. 134 * In : x0 - console base address 135 * Clobber list : x0, x1 136 * --------------------------------------------- 137 */ 138func console_core_getc 139 cbz x0, getc_error 140 141 /* Check if the receive FIFO is empty */ 1421: ldr w1, [x0, #UART_LSR] 143 tbz w1, #UART_LSR_DR, 1b 144 ldr w0, [x0, #UART_RBR] 145 ret 146getc_error: 147 mov w0, #-1 148 ret 149endfunc console_core_getc 150 151 /* --------------------------------------------- 152 * void console_core_flush(uintptr_t base_addr) 153 * Function to force a write of all buffered 154 * data that hasn't been output. 155 * In : x0 - console base address 156 * Out : void. 157 * Clobber list : x0, x1 158 * --------------------------------------------- 159 */ 160func console_core_flush 161 /* Placeholder */ 162 ret 163endfunc console_core_flush 164