19c94d3b3SSoby Mathew/* 2ad4c2ec6SAntonio Nino Diaz * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. 39c94d3b3SSoby Mathew * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 59c94d3b3SSoby Mathew */ 69c94d3b3SSoby Mathew#include <arch.h> 79c94d3b3SSoby Mathew#include <asm_macros.S> 838ba8e93SJulius Werner#include <assert_macros.S> 99c94d3b3SSoby Mathew#include <cadence/cdns_uart.h> 109c94d3b3SSoby Mathew 1138ba8e93SJulius Werner /* 1238ba8e93SJulius Werner * "core" functions are low-level implementations that don't require 1338ba8e93SJulius Werner * writable memory and are thus safe to call in BL1 crash context. 1438ba8e93SJulius Werner */ 1538ba8e93SJulius Werner .globl console_cdns_core_init 1638ba8e93SJulius Werner .globl console_cdns_core_putc 1738ba8e93SJulius Werner .globl console_cdns_core_getc 18*61d2b40dSAntonio Nino Diaz .globl console_cdns_core_flush 1938ba8e93SJulius Werner 2038ba8e93SJulius Werner .globl console_cdns_putc 2138ba8e93SJulius Werner .globl console_cdns_getc 22*61d2b40dSAntonio Nino Diaz .globl console_cdns_flush 239c94d3b3SSoby Mathew 249c94d3b3SSoby Mathew /* ----------------------------------------------- 2538ba8e93SJulius Werner * int console_cdns_core_init(uintptr_t base_addr) 269c94d3b3SSoby Mathew * Function to initialize the console without a 279c94d3b3SSoby Mathew * C Runtime to print debug information. This 289c94d3b3SSoby Mathew * function will be accessed by console_init and 299c94d3b3SSoby Mathew * crash reporting. 309c94d3b3SSoby Mathew * We assume that the bootloader already set up 319c94d3b3SSoby Mathew * the HW (baud, ...) and only enable the trans- 329c94d3b3SSoby Mathew * mitter and receiver here. 339c94d3b3SSoby Mathew * In: x0 - console base address 349c94d3b3SSoby Mathew * Out: return 1 on success else 0 on error 359c94d3b3SSoby Mathew * Clobber list : x1, x2, x3 369c94d3b3SSoby Mathew * ----------------------------------------------- 379c94d3b3SSoby Mathew */ 3838ba8e93SJulius Wernerfunc console_cdns_core_init 399c94d3b3SSoby Mathew /* Check the input base address */ 409c94d3b3SSoby Mathew cbz x0, core_init_fail 419c94d3b3SSoby Mathew 429c94d3b3SSoby Mathew /* RX/TX enabled & reset */ 439c94d3b3SSoby Mathew mov w3, #(R_UART_CR_TX_EN | R_UART_CR_RX_EN | R_UART_CR_TXRST | R_UART_CR_RXRST) 449c94d3b3SSoby Mathew str w3, [x0, #R_UART_CR] 459c94d3b3SSoby Mathew 469c94d3b3SSoby Mathew mov w0, #1 479c94d3b3SSoby Mathew ret 489c94d3b3SSoby Mathewcore_init_fail: 499c94d3b3SSoby Mathew mov w0, wzr 509c94d3b3SSoby Mathew ret 5138ba8e93SJulius Wernerendfunc console_cdns_core_init 5238ba8e93SJulius Werner 5338ba8e93SJulius Werner#if MULTI_CONSOLE_API 5438ba8e93SJulius Werner .globl console_cdns_register 5538ba8e93SJulius Werner 5638ba8e93SJulius Werner /* ----------------------------------------------- 5738ba8e93SJulius Werner * int console_cdns_register(console_cdns_t *console, 5838ba8e93SJulius Werner uintptr_t base, uint32_t clk, uint32_t baud) 5938ba8e93SJulius Werner * Function to initialize and register a new CDNS 6038ba8e93SJulius Werner * console. Storage passed in for the console struct 6138ba8e93SJulius Werner * *must* be persistent (i.e. not from the stack). 6238ba8e93SJulius Werner * In: x0 - UART register base address 6338ba8e93SJulius Werner * x1 - pointer to empty console_cdns_t struct 6438ba8e93SJulius Werner * Out: return 1 on success, 0 on error 6538ba8e93SJulius Werner * Clobber list : x0, x1, x2, x6, x7, x14 6638ba8e93SJulius Werner * ----------------------------------------------- 6738ba8e93SJulius Werner */ 6838ba8e93SJulius Wernerfunc console_cdns_register 6938ba8e93SJulius Werner mov x7, x30 7038ba8e93SJulius Werner mov x6, x1 7138ba8e93SJulius Werner cbz x6, register_fail 7238ba8e93SJulius Werner str x0, [x6, #CONSOLE_T_CDNS_BASE] 7338ba8e93SJulius Werner 7438ba8e93SJulius Werner bl console_cdns_core_init 7538ba8e93SJulius Werner cbz x0, register_fail 7638ba8e93SJulius Werner 7738ba8e93SJulius Werner mov x0, x6 7838ba8e93SJulius Werner mov x30, v7 7938ba8e93SJulius Werner finish_console_register cdns 8038ba8e93SJulius Werner 8138ba8e93SJulius Wernerregister_fail: 8238ba8e93SJulius Werner ret x7 8338ba8e93SJulius Wernerendfunc console_cdns_register 8438ba8e93SJulius Werner#else 8538ba8e93SJulius Werner .globl console_core_init 8638ba8e93SJulius Werner .globl console_core_putc 8738ba8e93SJulius Werner .globl console_core_getc 8838ba8e93SJulius Werner .globl console_core_flush 8938ba8e93SJulius Werner .equ console_core_init,console_cdns_core_init 9038ba8e93SJulius Werner .equ console_core_putc,console_cdns_core_putc 9138ba8e93SJulius Werner .equ console_core_getc,console_cdns_core_getc 92*61d2b40dSAntonio Nino Diaz .equ console_core_flush,console_cdns_core_flush 9338ba8e93SJulius Werner#endif 949c94d3b3SSoby Mathew 959c94d3b3SSoby Mathew /* -------------------------------------------------------- 9638ba8e93SJulius Werner * int console_cdns_core_putc(int c, uintptr_t base_addr) 979c94d3b3SSoby Mathew * Function to output a character over the console. It 989c94d3b3SSoby Mathew * returns the character printed on success or -1 on error. 999c94d3b3SSoby Mathew * In : w0 - character to be printed 1009c94d3b3SSoby Mathew * x1 - console base address 1019c94d3b3SSoby Mathew * Out : return -1 on error else return character. 1029c94d3b3SSoby Mathew * Clobber list : x2 1039c94d3b3SSoby Mathew * -------------------------------------------------------- 1049c94d3b3SSoby Mathew */ 10538ba8e93SJulius Wernerfunc console_cdns_core_putc 10638ba8e93SJulius Werner#if ENABLE_ASSERTIONS 10738ba8e93SJulius Werner cmp x1, #0 10838ba8e93SJulius Werner ASM_ASSERT(ne) 10938ba8e93SJulius Werner#endif /* ENABLE_ASSERTIONS */ 11038ba8e93SJulius Werner 1119c94d3b3SSoby Mathew /* Prepend '\r' to '\n' */ 1129c94d3b3SSoby Mathew cmp w0, #0xA 1139c94d3b3SSoby Mathew b.ne 2f 1149c94d3b3SSoby Mathew1: 1159c94d3b3SSoby Mathew /* Check if the transmit FIFO is full */ 1169c94d3b3SSoby Mathew ldr w2, [x1, #R_UART_SR] 1179c94d3b3SSoby Mathew tbnz w2, #UART_SR_INTR_TFUL_BIT, 1b 1189c94d3b3SSoby Mathew mov w2, #0xD 1199c94d3b3SSoby Mathew str w2, [x1, #R_UART_TX] 1209c94d3b3SSoby Mathew2: 1219c94d3b3SSoby Mathew /* Check if the transmit FIFO is full */ 1229c94d3b3SSoby Mathew ldr w2, [x1, #R_UART_SR] 1239c94d3b3SSoby Mathew tbnz w2, #UART_SR_INTR_TFUL_BIT, 2b 1249c94d3b3SSoby Mathew str w0, [x1, #R_UART_TX] 1259c94d3b3SSoby Mathew ret 12638ba8e93SJulius Wernerendfunc console_cdns_core_putc 12738ba8e93SJulius Werner 12838ba8e93SJulius Werner /* -------------------------------------------------------- 12938ba8e93SJulius Werner * int console_cdns_putc(int c, console_cdns_t *cdns) 13038ba8e93SJulius Werner * Function to output a character over the console. It 13138ba8e93SJulius Werner * returns the character printed on success or -1 on error. 13238ba8e93SJulius Werner * In : w0 - character to be printed 13338ba8e93SJulius Werner * x1 - pointer to console_t structure 13438ba8e93SJulius Werner * Out : return -1 on error else return character. 13538ba8e93SJulius Werner * Clobber list : x2 13638ba8e93SJulius Werner * -------------------------------------------------------- 13738ba8e93SJulius Werner */ 13838ba8e93SJulius Wernerfunc console_cdns_putc 13938ba8e93SJulius Werner#if ENABLE_ASSERTIONS 14038ba8e93SJulius Werner cmp x1, #0 14138ba8e93SJulius Werner ASM_ASSERT(ne) 14238ba8e93SJulius Werner#endif /* ENABLE_ASSERTIONS */ 14338ba8e93SJulius Werner ldr x1, [x1, #CONSOLE_T_CDNS_BASE] 14438ba8e93SJulius Werner b console_cdns_core_putc 14538ba8e93SJulius Wernerendfunc console_cdns_putc 1469c94d3b3SSoby Mathew 1479c94d3b3SSoby Mathew /* --------------------------------------------- 14838ba8e93SJulius Werner * int console_cdns_core_getc(uintptr_t base_addr) 1499c94d3b3SSoby Mathew * Function to get a character from the console. 1509c94d3b3SSoby Mathew * It returns the character grabbed on success 15138ba8e93SJulius Werner * or -1 if no character is available. 1529c94d3b3SSoby Mathew * In : x0 - console base address 15338ba8e93SJulius Werner * Out: w0 - character if available, else -1 1549c94d3b3SSoby Mathew * Clobber list : x0, x1 1559c94d3b3SSoby Mathew * --------------------------------------------- 1569c94d3b3SSoby Mathew */ 15738ba8e93SJulius Wernerfunc console_cdns_core_getc 15838ba8e93SJulius Werner#if ENABLE_ASSERTIONS 15938ba8e93SJulius Werner cmp x0, #0 16038ba8e93SJulius Werner ASM_ASSERT(ne) 16138ba8e93SJulius Werner#endif /* ENABLE_ASSERTIONS */ 16238ba8e93SJulius Werner 1639c94d3b3SSoby Mathew /* Check if the receive FIFO is empty */ 1649c94d3b3SSoby Mathew ldr w1, [x0, #R_UART_SR] 16538ba8e93SJulius Werner tbnz w1, #UART_SR_INTR_REMPTY_BIT, no_char 1669c94d3b3SSoby Mathew ldr w1, [x0, #R_UART_RX] 1679c94d3b3SSoby Mathew mov w0, w1 1689c94d3b3SSoby Mathew ret 16938ba8e93SJulius Wernerno_char: 17038ba8e93SJulius Werner mov w0, #ERROR_NO_PENDING_CHAR 1719c94d3b3SSoby Mathew ret 17238ba8e93SJulius Wernerendfunc console_cdns_core_getc 17338ba8e93SJulius Werner 17438ba8e93SJulius Werner /* --------------------------------------------- 17538ba8e93SJulius Werner * int console_cdns_getc(console_cdns_t *console) 17638ba8e93SJulius Werner * Function to get a character from the console. 17738ba8e93SJulius Werner * It returns the character grabbed on success 17838ba8e93SJulius Werner * or -1 if no character is available. 17938ba8e93SJulius Werner * In : x0 - pointer to console_t structure 18038ba8e93SJulius Werner * Out: w0 - character if available, else -1 18138ba8e93SJulius Werner * Clobber list : x0, x1 18238ba8e93SJulius Werner * --------------------------------------------- 18338ba8e93SJulius Werner */ 18438ba8e93SJulius Wernerfunc console_cdns_getc 18538ba8e93SJulius Werner#if ENABLE_ASSERTIONS 18638ba8e93SJulius Werner cmp x0, #0 18738ba8e93SJulius Werner ASM_ASSERT(ne) 18838ba8e93SJulius Werner#endif /* ENABLE_ASSERTIONS */ 18938ba8e93SJulius Werner ldr x0, [x0, #CONSOLE_T_CDNS_BASE] 19038ba8e93SJulius Werner b console_cdns_core_getc 19138ba8e93SJulius Wernerendfunc console_cdns_getc 192ad4c2ec6SAntonio Nino Diaz 193ad4c2ec6SAntonio Nino Diaz /* --------------------------------------------- 194*61d2b40dSAntonio Nino Diaz * int console_cdns_core_flush(uintptr_t base_addr) 195ad4c2ec6SAntonio Nino Diaz * Function to force a write of all buffered 196ad4c2ec6SAntonio Nino Diaz * data that hasn't been output. 197ad4c2ec6SAntonio Nino Diaz * In : x0 - console base address 198ad4c2ec6SAntonio Nino Diaz * Out : return -1 on error else return 0. 199ad4c2ec6SAntonio Nino Diaz * Clobber list : x0, x1 200ad4c2ec6SAntonio Nino Diaz * --------------------------------------------- 201ad4c2ec6SAntonio Nino Diaz */ 202*61d2b40dSAntonio Nino Diazfunc console_cdns_core_flush 203*61d2b40dSAntonio Nino Diaz#if ENABLE_ASSERTIONS 204*61d2b40dSAntonio Nino Diaz cmp x0, #0 205*61d2b40dSAntonio Nino Diaz ASM_ASSERT(ne) 206*61d2b40dSAntonio Nino Diaz#endif /* ENABLE_ASSERTIONS */ 207ad4c2ec6SAntonio Nino Diaz /* Placeholder */ 208ad4c2ec6SAntonio Nino Diaz mov w0, #0 209ad4c2ec6SAntonio Nino Diaz ret 210*61d2b40dSAntonio Nino Diazendfunc console_cdns_core_flush 211*61d2b40dSAntonio Nino Diaz 212*61d2b40dSAntonio Nino Diaz /* --------------------------------------------- 213*61d2b40dSAntonio Nino Diaz * int console_cdns_flush(console_pl011_t *console) 214*61d2b40dSAntonio Nino Diaz * Function to force a write of all buffered 215*61d2b40dSAntonio Nino Diaz * data that hasn't been output. 216*61d2b40dSAntonio Nino Diaz * In : x0 - pointer to console_t structure 217*61d2b40dSAntonio Nino Diaz * Out : return -1 on error else return 0. 218*61d2b40dSAntonio Nino Diaz * Clobber list : x0, x1 219*61d2b40dSAntonio Nino Diaz * --------------------------------------------- 220*61d2b40dSAntonio Nino Diaz */ 221*61d2b40dSAntonio Nino Diazfunc console_cdns_flush 222*61d2b40dSAntonio Nino Diaz#if ENABLE_ASSERTIONS 223*61d2b40dSAntonio Nino Diaz cmp x0, #0 224*61d2b40dSAntonio Nino Diaz ASM_ASSERT(ne) 225*61d2b40dSAntonio Nino Diaz#endif /* ENABLE_ASSERTIONS */ 226*61d2b40dSAntonio Nino Diaz ldr x0, [x0, #CONSOLE_T_CDNS_BASE] 227*61d2b40dSAntonio Nino Diaz b console_cdns_core_flush 228*61d2b40dSAntonio Nino Diazendfunc console_cdns_flush 229