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