1*66be868eSSoby Mathew/* 2*66be868eSSoby Mathew * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 3*66be868eSSoby Mathew * 4*66be868eSSoby Mathew * Redistribution and use in source and binary forms, with or without 5*66be868eSSoby Mathew * modification, are permitted provided that the following conditions are met: 6*66be868eSSoby Mathew * 7*66be868eSSoby Mathew * Redistributions of source code must retain the above copyright notice, this 8*66be868eSSoby Mathew * list of conditions and the following disclaimer. 9*66be868eSSoby Mathew * 10*66be868eSSoby Mathew * Redistributions in binary form must reproduce the above copyright notice, 11*66be868eSSoby Mathew * this list of conditions and the following disclaimer in the documentation 12*66be868eSSoby Mathew * and/or other materials provided with the distribution. 13*66be868eSSoby Mathew * 14*66be868eSSoby Mathew * Neither the name of ARM nor the names of its contributors may be used 15*66be868eSSoby Mathew * to endorse or promote products derived from this software without specific 16*66be868eSSoby Mathew * prior written permission. 17*66be868eSSoby Mathew * 18*66be868eSSoby Mathew * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19*66be868eSSoby Mathew * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*66be868eSSoby Mathew * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*66be868eSSoby Mathew * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22*66be868eSSoby Mathew * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*66be868eSSoby Mathew * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*66be868eSSoby Mathew * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*66be868eSSoby Mathew * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*66be868eSSoby Mathew * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*66be868eSSoby Mathew * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*66be868eSSoby Mathew * POSSIBILITY OF SUCH DAMAGE. 29*66be868eSSoby Mathew */ 30*66be868eSSoby Mathew#include <arch.h> 31*66be868eSSoby Mathew#include <asm_macros.S> 32*66be868eSSoby Mathew#include <pl011.h> 33*66be868eSSoby Mathew 34*66be868eSSoby Mathew/* 35*66be868eSSoby Mathew * Pull in generic functions to provide backwards compatibility for 36*66be868eSSoby Mathew * platform makefiles 37*66be868eSSoby Mathew */ 38*66be868eSSoby Mathew#include "../../../console/aarch32/console.S" 39*66be868eSSoby Mathew 40*66be868eSSoby Mathew .globl console_core_init 41*66be868eSSoby Mathew .globl console_core_putc 42*66be868eSSoby Mathew .globl console_core_getc 43*66be868eSSoby Mathew 44*66be868eSSoby Mathew 45*66be868eSSoby Mathew /* ----------------------------------------------- 46*66be868eSSoby Mathew * int console_core_init(uintptr_t base_addr, 47*66be868eSSoby Mathew * unsigned int uart_clk, unsigned int baud_rate) 48*66be868eSSoby Mathew * Function to initialize the console without a 49*66be868eSSoby Mathew * C Runtime to print debug information. This 50*66be868eSSoby Mathew * function will be accessed by console_init and 51*66be868eSSoby Mathew * crash reporting. 52*66be868eSSoby Mathew * In: r0 - console base address 53*66be868eSSoby Mathew * r1 - Uart clock in Hz 54*66be868eSSoby Mathew * r2 - Baud rate 55*66be868eSSoby Mathew * Out: return 1 on success else 0 on error 56*66be868eSSoby Mathew * Clobber list : r1, r2, r3 57*66be868eSSoby Mathew * ----------------------------------------------- 58*66be868eSSoby Mathew */ 59*66be868eSSoby Mathewfunc console_core_init 60*66be868eSSoby Mathew /* Check the input base address */ 61*66be868eSSoby Mathew cmp r0, #0 62*66be868eSSoby Mathew beq core_init_fail 63*66be868eSSoby Mathew#if !PL011_GENERIC_UART 64*66be868eSSoby Mathew /* Check baud rate and uart clock for sanity */ 65*66be868eSSoby Mathew cmp r1, #0 66*66be868eSSoby Mathew beq core_init_fail 67*66be868eSSoby Mathew cmp r2, #0 68*66be868eSSoby Mathew beq core_init_fail 69*66be868eSSoby Mathew /* Disable the UART before initialization */ 70*66be868eSSoby Mathew ldr r3, [r0, #UARTCR] 71*66be868eSSoby Mathew bic r3, r3, #PL011_UARTCR_UARTEN 72*66be868eSSoby Mathew str r3, [r0, #UARTCR] 73*66be868eSSoby Mathew /* Program the baudrate */ 74*66be868eSSoby Mathew /* Divisor = (Uart clock * 4) / baudrate */ 75*66be868eSSoby Mathew lsl r1, r1, #2 76*66be868eSSoby Mathew udiv r2, r1, r2 77*66be868eSSoby Mathew /* IBRD = Divisor >> 6 */ 78*66be868eSSoby Mathew lsr r1, r2, #6 79*66be868eSSoby Mathew /* Write the IBRD */ 80*66be868eSSoby Mathew str r1, [r0, #UARTIBRD] 81*66be868eSSoby Mathew /* FBRD = Divisor & 0x3F */ 82*66be868eSSoby Mathew and r1, r2, #0x3f 83*66be868eSSoby Mathew /* Write the FBRD */ 84*66be868eSSoby Mathew str r1, [r0, #UARTFBRD] 85*66be868eSSoby Mathew mov r1, #PL011_LINE_CONTROL 86*66be868eSSoby Mathew str r1, [r0, #UARTLCR_H] 87*66be868eSSoby Mathew /* Clear any pending errors */ 88*66be868eSSoby Mathew mov r1, #0 89*66be868eSSoby Mathew str r1, [r0, #UARTECR] 90*66be868eSSoby Mathew /* Enable tx, rx, and uart overall */ 91*66be868eSSoby Mathew ldr r1, =(PL011_UARTCR_RXE | PL011_UARTCR_TXE | PL011_UARTCR_UARTEN) 92*66be868eSSoby Mathew str r1, [r0, #UARTCR] 93*66be868eSSoby Mathew#endif 94*66be868eSSoby Mathew mov r0, #1 95*66be868eSSoby Mathew bx lr 96*66be868eSSoby Mathewcore_init_fail: 97*66be868eSSoby Mathew mov r0, #0 98*66be868eSSoby Mathew bx lr 99*66be868eSSoby Mathewendfunc console_core_init 100*66be868eSSoby Mathew 101*66be868eSSoby Mathew /* -------------------------------------------------------- 102*66be868eSSoby Mathew * int console_core_putc(int c, uintptr_t base_addr) 103*66be868eSSoby Mathew * Function to output a character over the console. It 104*66be868eSSoby Mathew * returns the character printed on success or -1 on error. 105*66be868eSSoby Mathew * In : r0 - character to be printed 106*66be868eSSoby Mathew * r1 - console base address 107*66be868eSSoby Mathew * Out : return -1 on error else return character. 108*66be868eSSoby Mathew * Clobber list : r2 109*66be868eSSoby Mathew * -------------------------------------------------------- 110*66be868eSSoby Mathew */ 111*66be868eSSoby Mathewfunc console_core_putc 112*66be868eSSoby Mathew /* Check the input parameter */ 113*66be868eSSoby Mathew cmp r1, #0 114*66be868eSSoby Mathew beq putc_error 115*66be868eSSoby Mathew /* Prepend '\r' to '\n' */ 116*66be868eSSoby Mathew cmp r0, #0xA 117*66be868eSSoby Mathew bne 2f 118*66be868eSSoby Mathew1: 119*66be868eSSoby Mathew /* Check if the transmit FIFO is full */ 120*66be868eSSoby Mathew ldr r2, [r1, #UARTFR] 121*66be868eSSoby Mathew tst r2, #PL011_UARTFR_TXFF_BIT 122*66be868eSSoby Mathew beq 1b 123*66be868eSSoby Mathew mov r2, #0xD 124*66be868eSSoby Mathew str r2, [r1, #UARTDR] 125*66be868eSSoby Mathew2: 126*66be868eSSoby Mathew /* Check if the transmit FIFO is full */ 127*66be868eSSoby Mathew ldr r2, [r1, #UARTFR] 128*66be868eSSoby Mathew tst r2, #PL011_UARTFR_TXFF_BIT 129*66be868eSSoby Mathew beq 2b 130*66be868eSSoby Mathew str r0, [r1, #UARTDR] 131*66be868eSSoby Mathew bx lr 132*66be868eSSoby Mathewputc_error: 133*66be868eSSoby Mathew mov r0, #-1 134*66be868eSSoby Mathew bx lr 135*66be868eSSoby Mathewendfunc console_core_putc 136*66be868eSSoby Mathew 137*66be868eSSoby Mathew /* --------------------------------------------- 138*66be868eSSoby Mathew * int console_core_getc(uintptr_t base_addr) 139*66be868eSSoby Mathew * Function to get a character from the console. 140*66be868eSSoby Mathew * It returns the character grabbed on success 141*66be868eSSoby Mathew * or -1 on error. 142*66be868eSSoby Mathew * In : r0 - console base address 143*66be868eSSoby Mathew * Clobber list : r0, r1 144*66be868eSSoby Mathew * --------------------------------------------- 145*66be868eSSoby Mathew */ 146*66be868eSSoby Mathewfunc console_core_getc 147*66be868eSSoby Mathew cmp r0, #0 148*66be868eSSoby Mathew beq getc_error 149*66be868eSSoby Mathew1: 150*66be868eSSoby Mathew /* Check if the receive FIFO is empty */ 151*66be868eSSoby Mathew ldr r1, [r0, #UARTFR] 152*66be868eSSoby Mathew tst r1, #PL011_UARTFR_RXFE_BIT 153*66be868eSSoby Mathew beq 1b 154*66be868eSSoby Mathew ldr r1, [r0, #UARTDR] 155*66be868eSSoby Mathew mov r0, r1 156*66be868eSSoby Mathew bx lr 157*66be868eSSoby Mathewgetc_error: 158*66be868eSSoby Mathew mov r0, #-1 159*66be868eSSoby Mathew bx lr 160*66be868eSSoby Mathewendfunc console_core_getc 161