166be868eSSoby Mathew/* 266be868eSSoby Mathew * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 366be868eSSoby Mathew * 466be868eSSoby Mathew * Redistribution and use in source and binary forms, with or without 566be868eSSoby Mathew * modification, are permitted provided that the following conditions are met: 666be868eSSoby Mathew * 766be868eSSoby Mathew * Redistributions of source code must retain the above copyright notice, this 866be868eSSoby Mathew * list of conditions and the following disclaimer. 966be868eSSoby Mathew * 1066be868eSSoby Mathew * Redistributions in binary form must reproduce the above copyright notice, 1166be868eSSoby Mathew * this list of conditions and the following disclaimer in the documentation 1266be868eSSoby Mathew * and/or other materials provided with the distribution. 1366be868eSSoby Mathew * 1466be868eSSoby Mathew * Neither the name of ARM nor the names of its contributors may be used 1566be868eSSoby Mathew * to endorse or promote products derived from this software without specific 1666be868eSSoby Mathew * prior written permission. 1766be868eSSoby Mathew * 1866be868eSSoby Mathew * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1966be868eSSoby Mathew * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2066be868eSSoby Mathew * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2166be868eSSoby Mathew * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2266be868eSSoby Mathew * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2366be868eSSoby Mathew * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2466be868eSSoby Mathew * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2566be868eSSoby Mathew * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2666be868eSSoby Mathew * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2766be868eSSoby Mathew * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2866be868eSSoby Mathew * POSSIBILITY OF SUCH DAMAGE. 2966be868eSSoby Mathew */ 3066be868eSSoby Mathew#include <arch.h> 3166be868eSSoby Mathew#include <asm_macros.S> 3266be868eSSoby Mathew#include <pl011.h> 3366be868eSSoby Mathew 3466be868eSSoby Mathew/* 3566be868eSSoby Mathew * Pull in generic functions to provide backwards compatibility for 3666be868eSSoby Mathew * platform makefiles 3766be868eSSoby Mathew */ 3866be868eSSoby Mathew#include "../../../console/aarch32/console.S" 3966be868eSSoby Mathew 4066be868eSSoby Mathew .globl console_core_init 4166be868eSSoby Mathew .globl console_core_putc 4266be868eSSoby Mathew .globl console_core_getc 4366be868eSSoby Mathew 4466be868eSSoby Mathew 4566be868eSSoby Mathew /* ----------------------------------------------- 4666be868eSSoby Mathew * int console_core_init(uintptr_t base_addr, 4766be868eSSoby Mathew * unsigned int uart_clk, unsigned int baud_rate) 4866be868eSSoby Mathew * Function to initialize the console without a 4966be868eSSoby Mathew * C Runtime to print debug information. This 5066be868eSSoby Mathew * function will be accessed by console_init and 5166be868eSSoby Mathew * crash reporting. 5266be868eSSoby Mathew * In: r0 - console base address 5366be868eSSoby Mathew * r1 - Uart clock in Hz 5466be868eSSoby Mathew * r2 - Baud rate 5566be868eSSoby Mathew * Out: return 1 on success else 0 on error 5666be868eSSoby Mathew * Clobber list : r1, r2, r3 5766be868eSSoby Mathew * ----------------------------------------------- 5866be868eSSoby Mathew */ 5966be868eSSoby Mathewfunc console_core_init 6066be868eSSoby Mathew /* Check the input base address */ 6166be868eSSoby Mathew cmp r0, #0 6266be868eSSoby Mathew beq core_init_fail 6366be868eSSoby Mathew#if !PL011_GENERIC_UART 6466be868eSSoby Mathew /* Check baud rate and uart clock for sanity */ 6566be868eSSoby Mathew cmp r1, #0 6666be868eSSoby Mathew beq core_init_fail 6766be868eSSoby Mathew cmp r2, #0 6866be868eSSoby Mathew beq core_init_fail 6966be868eSSoby Mathew /* Disable the UART before initialization */ 7066be868eSSoby Mathew ldr r3, [r0, #UARTCR] 7166be868eSSoby Mathew bic r3, r3, #PL011_UARTCR_UARTEN 7266be868eSSoby Mathew str r3, [r0, #UARTCR] 7366be868eSSoby Mathew /* Program the baudrate */ 7466be868eSSoby Mathew /* Divisor = (Uart clock * 4) / baudrate */ 7566be868eSSoby Mathew lsl r1, r1, #2 7666be868eSSoby Mathew udiv r2, r1, r2 7766be868eSSoby Mathew /* IBRD = Divisor >> 6 */ 7866be868eSSoby Mathew lsr r1, r2, #6 7966be868eSSoby Mathew /* Write the IBRD */ 8066be868eSSoby Mathew str r1, [r0, #UARTIBRD] 8166be868eSSoby Mathew /* FBRD = Divisor & 0x3F */ 8266be868eSSoby Mathew and r1, r2, #0x3f 8366be868eSSoby Mathew /* Write the FBRD */ 8466be868eSSoby Mathew str r1, [r0, #UARTFBRD] 8566be868eSSoby Mathew mov r1, #PL011_LINE_CONTROL 8666be868eSSoby Mathew str r1, [r0, #UARTLCR_H] 8766be868eSSoby Mathew /* Clear any pending errors */ 8866be868eSSoby Mathew mov r1, #0 8966be868eSSoby Mathew str r1, [r0, #UARTECR] 9066be868eSSoby Mathew /* Enable tx, rx, and uart overall */ 9166be868eSSoby Mathew ldr r1, =(PL011_UARTCR_RXE | PL011_UARTCR_TXE | PL011_UARTCR_UARTEN) 9266be868eSSoby Mathew str r1, [r0, #UARTCR] 9366be868eSSoby Mathew#endif 9466be868eSSoby Mathew mov r0, #1 9566be868eSSoby Mathew bx lr 9666be868eSSoby Mathewcore_init_fail: 9766be868eSSoby Mathew mov r0, #0 9866be868eSSoby Mathew bx lr 9966be868eSSoby Mathewendfunc console_core_init 10066be868eSSoby Mathew 10166be868eSSoby Mathew /* -------------------------------------------------------- 10266be868eSSoby Mathew * int console_core_putc(int c, uintptr_t base_addr) 10366be868eSSoby Mathew * Function to output a character over the console. It 10466be868eSSoby Mathew * returns the character printed on success or -1 on error. 10566be868eSSoby Mathew * In : r0 - character to be printed 10666be868eSSoby Mathew * r1 - console base address 10766be868eSSoby Mathew * Out : return -1 on error else return character. 10866be868eSSoby Mathew * Clobber list : r2 10966be868eSSoby Mathew * -------------------------------------------------------- 11066be868eSSoby Mathew */ 11166be868eSSoby Mathewfunc console_core_putc 11266be868eSSoby Mathew /* Check the input parameter */ 11366be868eSSoby Mathew cmp r1, #0 11466be868eSSoby Mathew beq putc_error 11566be868eSSoby Mathew /* Prepend '\r' to '\n' */ 11666be868eSSoby Mathew cmp r0, #0xA 11766be868eSSoby Mathew bne 2f 11866be868eSSoby Mathew1: 11966be868eSSoby Mathew /* Check if the transmit FIFO is full */ 12066be868eSSoby Mathew ldr r2, [r1, #UARTFR] 121*69d59e0cSYatharth Kochar tst r2, #PL011_UARTFR_TXFF 122*69d59e0cSYatharth Kochar bne 1b 12366be868eSSoby Mathew mov r2, #0xD 12466be868eSSoby Mathew str r2, [r1, #UARTDR] 12566be868eSSoby Mathew2: 12666be868eSSoby Mathew /* Check if the transmit FIFO is full */ 12766be868eSSoby Mathew ldr r2, [r1, #UARTFR] 128*69d59e0cSYatharth Kochar tst r2, #PL011_UARTFR_TXFF 129*69d59e0cSYatharth Kochar bne 2b 13066be868eSSoby Mathew str r0, [r1, #UARTDR] 13166be868eSSoby Mathew bx lr 13266be868eSSoby Mathewputc_error: 13366be868eSSoby Mathew mov r0, #-1 13466be868eSSoby Mathew bx lr 13566be868eSSoby Mathewendfunc console_core_putc 13666be868eSSoby Mathew 13766be868eSSoby Mathew /* --------------------------------------------- 13866be868eSSoby Mathew * int console_core_getc(uintptr_t base_addr) 13966be868eSSoby Mathew * Function to get a character from the console. 14066be868eSSoby Mathew * It returns the character grabbed on success 14166be868eSSoby Mathew * or -1 on error. 14266be868eSSoby Mathew * In : r0 - console base address 14366be868eSSoby Mathew * Clobber list : r0, r1 14466be868eSSoby Mathew * --------------------------------------------- 14566be868eSSoby Mathew */ 14666be868eSSoby Mathewfunc console_core_getc 14766be868eSSoby Mathew cmp r0, #0 14866be868eSSoby Mathew beq getc_error 14966be868eSSoby Mathew1: 15066be868eSSoby Mathew /* Check if the receive FIFO is empty */ 15166be868eSSoby Mathew ldr r1, [r0, #UARTFR] 152*69d59e0cSYatharth Kochar tst r1, #PL011_UARTFR_RXFE 153*69d59e0cSYatharth Kochar bne 1b 15466be868eSSoby Mathew ldr r1, [r0, #UARTDR] 15566be868eSSoby Mathew mov r0, r1 15666be868eSSoby Mathew bx lr 15766be868eSSoby Mathewgetc_error: 15866be868eSSoby Mathew mov r0, #-1 15966be868eSSoby Mathew bx lr 16066be868eSSoby Mathewendfunc console_core_getc 161